﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using System.IO;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using System.Collections;
using MS.InformationManagement.Support.FileCreator;
using Office = Microsoft.Office.DocumentManagement.DocumentSets;
using System.Web;
using MS.InformationManagement.Support.Constants;

namespace MS.InformationManagement.Support
{
    public class OfficeWordHelper
    {

        public static string GenerarWordFromTemplate(string documentLibraryTemplate, string TemplateFileName, string documentDestinyLibraryName, Hashtable Content)
        {
            string result = string.Empty;
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (SPSite currentSite = new SPSite(SPContext.Current.Web.Url))
                {
                    using (SPWeb currentWeb = currentSite.OpenWeb())
                    {
                        SPList list = currentWeb.Lists[documentLibraryTemplate];
                        list.ParentWeb.AllowUnsafeUpdates = true;
                        SPQuery query = new SPQuery();
                        query.ViewFields = "<FieldRef Name='FileLeafRef' />";
                        query.Query = "<Where><Eq><FieldRef Name='FileLeafRef' /><Value Type='Text'>" + TemplateFileName + @"</Value></Eq></Where>";

                        SPListItemCollection collection = list.GetItems(query);
                        SPFile file = collection[0].File;
                        byte[] byteArray = file.OpenBinary();

                        using (MemoryStream mem = new MemoryStream())
                        {
                            mem.Write(byteArray, 0, (int)byteArray.Length);

                            using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(mem, true))
                            {
                                foreach (string field in Content.Keys)
                                {
                                    Paragraph paragraph = (from Paragraph par in wordDoc.MainDocumentPart.Document.Body.Elements<Paragraph>()
                                                           where par.InnerText.Contains(field)
                                                           select par).FirstOrDefault();

                                    MS.InformationManagement.Support.FileCreator.FileCreator obj = (MS.InformationManagement.Support.FileCreator.FileCreator)Content[field];

                                    if (paragraph != null)
                                    {
                                        if (obj.Element != null)
                                        {
                                            if (obj.Element is Table)
                                            {
                                                addTableToDocument(field, (Table)obj.Element, wordDoc);
                                            }
                                        }
                                        else
                                        {
                                            string text = paragraph.InnerText.Replace(field, obj.Text);
                                            Paragraph periodoParagraph = addParagraph(text, obj.isBold, obj.FontName.ToString(), obj.FontSize.ToString(), obj.HorizontallyAlign);
                                            paragraph.Parent.InsertBefore(periodoParagraph, paragraph);
                                            paragraph.RemoveAllChildren();
                                            paragraph.Remove();
                                        }
                                    }
                                }

                            }
                            result = UploadDocument(currentWeb, documentDestinyLibraryName, mem);
                            file.Update();
                        }
                    }
                }
            });

            return result;
        }

        public static SPFile RemplazarWordFromTemplate(byte[] byteArray, Hashtable Content, Office.DocumentSet updatedDocSet, string FileName, bool isMainDocument)
        {
            SPFile file = null;
            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (SPSite currentSite = new SPSite(SPContext.Current.Web.Url))
                {
                    using (SPWeb currentWeb = currentSite.OpenWeb())
                    {
                        using (MemoryStream mem = new MemoryStream())
                        {
                            mem.Write(byteArray, 0, (int)byteArray.Length);

                            using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(mem, true))
                            {
                                foreach (string field in Content.Keys)
                                {
                                    //DocumentFormat.OpenXml.Wordprocessing.Footer
                                    List<Paragraph> listParagraph = (from Paragraph par in wordDoc.MainDocumentPart.Document.Body.Elements<Paragraph>()
                                                                     where par.InnerText.Contains(field)
                                                                     select par).ToList();

                                    MS.InformationManagement.Support.FileCreator.FileCreator obj = (MS.InformationManagement.Support.FileCreator.FileCreator)Content[field];

                                    if (listParagraph != null)
                                    {
                                        if (obj.Element != null)
                                        {
                                            if (obj.Element is Table)
                                            {
                                                addTableToDocument(field, (Table)obj.Element, wordDoc);
                                            }
                                        }
                                        else
                                        {
                                            foreach (Paragraph paragraph in listParagraph)
                                            {
                                                string text = paragraph.InnerText.Replace(field, obj.Text);
                                                Paragraph periodoParagraph = addParagraph(text, obj.isBold, obj.FontName.ToString(), obj.FontSize.ToString(), obj.HorizontallyAlign);
                                                paragraph.Parent.InsertBefore(periodoParagraph, paragraph);
                                                paragraph.RemoveAllChildren();
                                                paragraph.Remove();
                                            }
                                        }
                                    }
                                }
                            }
                            Hashtable fileProperties = new Hashtable();
                            fileProperties.Add(CustomSiteColumns.FIELD_DOCUMENT_IS_MAIN, isMainDocument);
                            file = updatedDocSet.Folder.Files.Add(FileName, mem, fileProperties, true);
                        }
                    }
                }
            });

            return file;
        }

        public static void addTableToDocument(string Etiqueta, DocumentFormat.OpenXml.Wordprocessing.Table table, WordprocessingDocument wordDoc)
        {
            Paragraph pr = (from Paragraph firma in wordDoc.MainDocumentPart.Document.Body.Elements<Paragraph>()
                            where firma.InnerText == Etiqueta
                            select firma).FirstOrDefault();
            if (pr != null)
            {
                Paragraph tablaRadicados = new Paragraph(new Run(new Text("")));
                tablaRadicados.Append(table);
                pr.Parent.InsertBefore(tablaRadicados, pr);

                pr.RemoveAllChildren();
                pr.Remove();
            }
        }

        public static Paragraph addParagraph(string text, bool isBold, string fontName, string fontize, JustificationValues justificationValues)
        {

            Paragraph paragraph1 = new Paragraph() { RsidParagraphAddition = "004F7104", RsidParagraphProperties = "008F2986", RsidRunAdditionDefault = "004F7104" };

            ParagraphProperties paragraphProperties1 = new ParagraphProperties();
            Justification justification1 = new Justification() { Val = justificationValues };

            paragraphProperties1.Append(justification1);

            Run run1 = new Run();

            RunProperties runProperties1 = new RunProperties();

            RunFonts runFonts1 = new RunFonts(); //{ Hint = FontTypeHintValues.EastAsia };
            runFonts1.Ascii = fontName;

            DocumentFormat.OpenXml.Wordprocessing.FontSize fontSize = new DocumentFormat.OpenXml.Wordprocessing.FontSize();
            fontSize.Val = fontize;

            Bold bold1 = new Bold();

            runProperties1.Append(fontSize);
            runProperties1.Append(runFonts1);
            if (isBold)
                runProperties1.AppendChild(bold1);

            Text text1 = new Text();
            text1.Text = text;

            run1.Append(runProperties1);
            run1.Append(text1);

            paragraph1.Append(paragraphProperties1);
            paragraph1.Append(run1);
            return paragraph1;
        }

        private static string UploadDocument(SPWeb currentWeb, string documentDestinyLibraryName, MemoryStream mem)
        {
            string result = string.Empty;
            Guid g = Guid.NewGuid();
            SPList docLib = currentWeb.Lists[documentDestinyLibraryName];
            SPFile filess = docLib.RootFolder.Files.Add(g + ".docx", mem, true);
            result = filess.Item.ID.ToString();
            return result;
        }

        public static void RemoveCoreProperties(MemoryStream officeFileStream, string fileExtension)
        {
            OpenXmlPackage doc = null;
            try
            {
                switch (fileExtension)
                {
                    case "docx":
                    case "doc":
                        doc = WordprocessingDocument.Open(officeFileStream, true);
                        break;
                    case "xls":
                    case "xlsx":
                        doc = SpreadsheetDocument.Open(officeFileStream, true);
                        break;
                    case "ppt":
                    case "pptx":
                        doc = PresentationDocument.Open(officeFileStream, true);
                        break;
                }
                RemoveCoreProperties(doc);
            }
            catch (FileFormatException ex) {
                throw new FileFormatException("Formato de archivo incorrecto. Verifique que el archivo sea de una version igual o superior a office 2010 y que no se encuentre corrupto");
            }
            catch (Exception ex)
            {
                throw;
            }
            finally {
                if (doc != null) { doc.Dispose(); }
            }
        }

        private static void RemoveCoreProperties(OpenXmlPackage officePackage) {
            if (!string.IsNullOrEmpty(officePackage.PackageProperties.Title)
                || !string.IsNullOrEmpty(officePackage.PackageProperties.Subject)
                || !string.IsNullOrEmpty(officePackage.PackageProperties.Keywords)
                || !string.IsNullOrEmpty(officePackage.PackageProperties.Description))
            {
                throw new Exception("El archivo que esta intentando cargar contiene metadata embebida. Este tipo de metadatos no son soportados");
            }
        }
    }
}
